#!/bin/bash
# Filename     : create-admin-account.sh
# Last modified: 2024-08-30 12:12
# Version      : 1.0.0
# Author       : jack.zang
# Email        : jack.zang@aishangwei.net
# Description  : Kubernetes超级管理员账户创建脚本
# 使用方法：(source <(curl -sL https://gitee.com/jack_zang/public-scripts/raw/master/shell/k8s/create-admin-account.sh))
# ******************************************************
set -euo pipefail

# 定义变量
SA_NAME="admin-user"
SECRET_NAME="${SA_NAME}-token"
KUBECONFIG_FILE="admin-kubeconfig.yaml"

####################### 输出日志 - start #######################
# 设置日志颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}
####################### 输出日志 - end #######################

# 检查kubectl命令是否可用
if ! command -v kubectl &> /dev/null; then
    log_error "kubectl命令未找到，请确保已安装kubectl并配置正确"
    exit 1
fi

# 创建临时目录存储 YAML 文件
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT

# 1. 创建 ServiceAccount、ClusterRole 和 ClusterRoleBinding
cat > "$TMP_DIR/rbac-config.yaml" << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: $SA_NAME
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: admin-cluster-role
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-binding
subjects:
- kind: ServiceAccount
  name: $SA_NAME
  namespace: default
roleRef:
  kind: ClusterRole
  name: admin-cluster-role
  apiGroup: rbac.authorization.k8s.io
EOF

# 应用 RBAC 配置
log_info "应用 RBAC 配置..."
kubectl apply -f "$TMP_DIR/rbac-config.yaml"

# 2. 创建 ServiceAccount 令牌
cat > "$TMP_DIR/token-secret.yaml" << EOF
apiVersion: v1
kind: Secret
metadata:
  name: $SECRET_NAME
  annotations:
    kubernetes.io/service-account.name: $SA_NAME
type: kubernetes.io/service-account-token
EOF

# 应用令牌配置
log_info "创建服务账户令牌..."
kubectl apply -f "$TMP_DIR/token-secret.yaml"

# 等待令牌准备就绪
log_info "等待令牌生成..."
until kubectl get secret "$SECRET_NAME" -o jsonpath='{.data.token}' > /dev/null 2>&1; do
  sleep 1
done

# 3. 获取必要的集群信息
log_info "收集集群信息..."
TOKEN=$(kubectl get secret "$SECRET_NAME" -o jsonpath='{.data.token}' | base64 -d)
CLUSTER_NAME=$(kubectl config current-context)
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')

# 获取 CA 证书（优先从 configmap 获取，失败则从配置中获取）
if CA_CERT=$(kubectl get configmap kube-root-ca.crt -n kube-system -o jsonpath='{.data.ca\.crt}' 2>/dev/null | base64 -w0); then
  log_info "从 kube-root-ca.crt 获取 CA 证书"
else
  log_info "从当前配置获取 CA 证书"
  CA_CERT=$(kubectl config view --raw -o jsonpath='{range .clusters[*]}{.cluster.certificate-authority-data}{end}')
fi

# 4. 生成 kubeconfig 文件
log_info "生成 kubeconfig 文件..."
cat > "$KUBECONFIG_FILE" << EOF
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: $CA_CERT
    server: $SERVER
  name: $CLUSTER_NAME
contexts:
- context:
    cluster: $CLUSTER_NAME
    user: $SA_NAME
  name: admin-context
current-context: admin-context
kind: Config
preferences: {}
users:
- name: $SA_NAME
  user:
    token: $TOKEN
EOF

log_info "操作完成！"
log_info "生成的超级管理员配置文件：$KUBECONFIG_FILE"
log_info "使用方法：export KUBECONFIG=$PWD/$KUBECONFIG_FILE"
log_info "警告：此配置文件包含对集群的完全访问权限，请妥善保管！"